package com.internetCafes.spms.common.AIRecognize.handler.impl;

import com.hankcs.hanlp.seg.common.Term;
import com.hankcs.hanlp.tokenizer.StandardTokenizer;
import com.internetCafes.spms.common.AIRecognize.handler.WordHandler;
import com.internetCafes.spms.common.utils.IdCardUtils;
import com.internetCafes.spms.web.certificate.vo.AIRecognizeInfo;
import org.ansj.domain.Result;
import org.ansj.splitWord.analysis.DicAnalysis;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author LinYe
 * @date 2020/10/14
 */
@Component
public class CommonWordHandler implements WordHandler {

    /**
     * 使用分词工具对字符串进行解析后，根据词性获取实体类对应属性
     *
     * @param word
     * @param filePath 图片路径
     * @return 智能识别实体类
     */
    @Override
    public AIRecognizeInfo handle(String word, String filePath) {
        AIRecognizeInfo aiRecognizeInfo = new AIRecognizeInfo();
        Result parse = DicAnalysis.parse(word);
        aiRecognizeInfo.setProfession(handleProfession(parse));
        aiRecognizeInfo.setName(handleName(parse, word));
        String[] certificateNoAndIdCard = handleCertificateNoAndIdCard(parse, word);
        if (certificateNoAndIdCard[0] != null) {
            aiRecognizeInfo.setIdCard(certificateNoAndIdCard[0]);
        }
        if (certificateNoAndIdCard[1] != null) {
            aiRecognizeInfo.setCertificateNo(certificateNoAndIdCard[1]);
        }
        return aiRecognizeInfo;
    }

    /**
     * 根据分词后结果获取身份证号和证书号
     *
     * @param parse 分词工具解析结果类
     * @param word  原字符串
     * @return String数组，下标0为身份证号，下标1为证书号
     */
    private String[] handleCertificateNoAndIdCard(Result parse, String word) {
        List<org.ansj.domain.Term> terms = parse.getTerms();
        List<String> numberType = new ArrayList<>();
        String[] certificateNoAndIdCard = new String[2];
        for (int i = 0; i < terms.size(); i++) {
            org.ansj.domain.Term term = terms.get(i);
            if (term.toString().contains("/m")) {
                int index = term.toString().indexOf("/m");
                numberType.add(term.toString().substring(0, index));
            }
        }
        numberType = new ArrayList<>(new HashSet<>(numberType));
        String[] strings = word.split("\n");
        for (int i = 0; i < strings.length; i++) {
            String idCard = strings[i];
            String regEx = "[^0-9xX]";
            Pattern pattern = Pattern.compile(regEx);
            Matcher matcher = pattern.matcher(idCard);
            idCard = matcher.replaceAll("").trim();
            if (IdCardUtils.validateCard(idCard)) {
                regEx = "[^0-9]";
                pattern = Pattern.compile(regEx);
                matcher = pattern.matcher(idCard);
                numberType.remove(matcher.replaceAll("").trim());
                certificateNoAndIdCard[0] = idCard;
                break;
            }
        }
        if (certificateNoAndIdCard[0] != null) {
            for (int i = 0; i < strings.length; i++) {
                if (strings[i].contains(certificateNoAndIdCard[0])) {
                    strings[i] = "";
                }
            }
        }
        if (CollectionUtils.isEmpty(numberType)) {
            return certificateNoAndIdCard;
        }
        String certificateNo = numberType.get(0);
        for (int i = 1; i < numberType.size(); i++) {
            String number = numberType.get(i);
            if (number.length() > certificateNo.length() && number.length() < 20 && number.length() >= 5) {
                certificateNo = number;
            }
        }
        if (certificateNo.length() < 5) {
            return certificateNoAndIdCard;
        }
        certificateNo = certificateNo.replace(",", "");
        for (int i = 0; i < strings.length; i++) {
            String s = strings[i];
            if (s.contains(certificateNo)) {
                if (s.contains(":")) {
                    int removePrefix = s.indexOf(":");
                    s = s.substring(removePrefix + 1);
                }
                if (s.contains("：")) {
                    int removePrefix = s.indexOf("：");
                    s = s.substring(removePrefix + 1);
                }
                certificateNoAndIdCard[1] = s;
                break;
            }
        }
        return certificateNoAndIdCard;
    }

    /**
     * 根据分词后结果获取姓名，如识别失败。使用第二种分词工具进行识别解析。
     *
     * @param parse 分词工具解析结果类
     * @param word  原字符串
     * @return 姓名
     */
    public String handleName(Result parse, String word) {
        List<org.ansj.domain.Term> terms = parse.getTerms();
        List<String> names = new ArrayList<>();
        String[] split = word.split("\n");
        for (int i = 0; i < terms.size(); i++) {
            org.ansj.domain.Term term = terms.get(i);
            if (term.toString().endsWith("/nr") && term.toString().length() > 4) {
                String name = term.toString();
                name = name.substring(0, name.length() - "/nr".length());
                names.add(name);
            }
        }
        if (CollectionUtils.isNotEmpty(names)) {
            for (String name : names) {
                for (int i = 0; i < split.length; i++) {
                    String s = split[i];
                    if (s.contains(name)) {
                        if (s.contains(":")) {
                            int removePrefix = s.indexOf(":");
                            s = s.substring(removePrefix + 1);
                        }
                        if (s.length() < 5) {
                            return s;
                        }
                    }
                }
            }
        }
        List<Term> termList = StandardTokenizer.segment(word);
        for (int i = 0; i < termList.size(); i++) {
            Term term = termList.get(i);
            if (term.toString().contains("/nr") && term.toString().length() > 4) {
                String name = term.toString();
                name = name.substring(0, name.length() - "/nr".length());
                names.add(name);
            }
        }
        if (CollectionUtils.isNotEmpty(names)) {
            for (String name : names) {
                for (int i = 0; i < split.length; i++) {
                    String s = split[i];
                    if (s.contains(name)) {
                        if (s.contains(":")) {
                            int removePrefix = s.indexOf(":");
                            s = s.substring(removePrefix + 1);
                        }
                        if (s.length() < 5) {
                            return s;
                        }
                    }
                }
            }
        }
        return null;
    }

    /**
     * 根据分词工具的自定义词典功能获取对应专业
     *
     * @param parse 分词工具处理后结果
     * @return 专业
     */
    public String handleProfession(Result parse) {
        List<org.ansj.domain.Term> terms = parse.getTerms();
        List<String> professionList = new ArrayList<>();
        String result = "";
        for (int i = 0; i < terms.size(); i++) {
            org.ansj.domain.Term term = terms.get(i);
            if (term.toString().contains("/pro")) {
                String profession = term.toString();
                profession = profession.substring(0, profession.length() - "/pro".length());
                professionList.add(profession);
            }
        }
        if (professionList.size() == 0) {
            return null;
        }
        for (int i = 0; i < professionList.size(); i++) {
            String profession = professionList.get(i);
            if (profession.length() > result.length()) {
                result = profession;
            }
        }
        return result;
    }
}
